package com.zg.generator.web;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.zg.common.core.A;
import com.zg.common.core.R;
import com.zg.common.core.dao.generator.GenColumn;
import com.zg.common.core.dao.generator.GenColumnDao;
import com.zg.common.core.vo.ColumnVo;
import com.zg.common.web.service.DdlService;
import com.zg.generator.service.EngineService;
import com.zg.generator.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.List;

/**
 * @author Zxb
 */
@RestController
@AllArgsConstructor
@Api(tags = {"代码生成配置管理"})
public class ConfigController {

    private GenColumnDao columnDao;
    private EngineService engineService;
    private DdlService ddlService;

    @ApiOperation("设置字段属性")
    @PostMapping("/config/column/property/set")
    @Transactional(rollbackFor = Exception.class)
    public R<?> setColumnErrorMsg(@RequestBody StrProSetVo param) {
        String tableName = param.getTableName();
        String columnName = param.getColumnName();
        String propertyName = param.getPropertyName();
        String propertyValue = param.getPropertyValue();
        GenColumn column = engineService.findGenColumnByTable(tableName, columnName);
        A.isInDatabase(column, "字段");
        try {
            Field field = GenColumn.class.getDeclaredField(propertyName);
            Class<?> fieldType = field.getType();
            String methodName = "set" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
            Method method = GenColumn.class.getDeclaredMethod(methodName, fieldType);
            if (fieldType == Long.class) {
                method.invoke(column, Long.valueOf(propertyValue));
            } else if (fieldType == Integer.class) {
                method.invoke(column, Integer.valueOf(propertyValue));
            } else if (fieldType == Double.class) {
                method.invoke(column, Double.valueOf(propertyValue));
            } else if (fieldType == String.class) {
                method.invoke(column, propertyValue);
            } else if (fieldType == Boolean.class) {
                method.invoke(column, "true".equals(propertyValue));
            } else if (fieldType == Date.class) {
                method.invoke(column, new Date(DateUtil.parse(propertyValue).getTime()));
            } else if (fieldType == Timestamp.class) {
                method.invoke(column, new Timestamp(DateUtil.parse(propertyValue).getTime()));
            } else if (fieldType == Time.class) {
                method.invoke(column, new Time(DateUtil.parse(propertyValue).getTime()));
            }
            columnDao.updateById(column);
            String sortColumnName = "isSort";
            String trueValue = "true";
            if (propertyName.equals(sortColumnName) && trueValue.equals(propertyValue)) {
                //如果是排序字段，只能设置一个
                columnDao.update(
                        new LambdaUpdateWrapper<GenColumn>()
                                .eq(GenColumn::getTableName, tableName)
                                .ne(GenColumn::getId, column.getId())
                                .set(GenColumn::getIsSort, false)
                );
            }
            return R.success();
        } catch (NoSuchFieldException e) {
            return R.error("属性名不存在");
        } catch (NoSuchMethodException e) {
            return R.error("set方法不存在");
        } catch (InvocationTargetException e) {
            return R.error("设值过程出现错误");
        } catch (IllegalAccessException e) {
            return R.error("设值过程出现错误");
        }
    }

    @ApiOperation("查询表的代码生成配置")
    @PostMapping("/config/column/list")
    public R<?> listCol(@RequestBody TableVo param) {
        String schema = param.getSchema();
        String tableName = param.getTableName();
        List<GenColumn> list = engineService.listColumn(schema, tableName);
        return R.success(list);
    }

    @ApiOperation("初始化表的代码生成配置")
    @PostMapping("/config/column/init")
    public R<?> initCol(@RequestBody TableVo param) {
        String schema = param.getSchema();
        String tableName = param.getTableName();
        List<ColumnVo> columnList = ddlService.findColumnByTable(tableName, schema);
        List<GenColumn> list = engineService.initTable(schema, tableName, columnList);
        return R.success(list);
    }

    @ApiOperation("删除表字段的代码生成配置")
    @PostMapping("/config/column/del")
    public R<?> delCol(@RequestBody ColumnDelVo param) {
        String schema = param.getSchema();
        String tableName = param.getTableName();
        String columnName = param.getColumnName();
        columnDao.remove(
                new LambdaQueryWrapper<GenColumn>()
                        .eq(GenColumn::getTableName, tableName)
                        .eq(GenColumn::getColumnName, columnName)
        );
        return R.success();
    }
}
